#!/bin/bash
# * =====================================================
# * Copyright © hk. 2022-2025. All rights reserved.
# * File name  : setup-basic.sh
# * Author     : 苏木
# * Date       : 2025-10-19
# * Version    : 
# * Description: 
# * ======================================================
##

# 计算脚本的绝对路径，确保能正确引用 common.sh
SCRIPT_NAME=${0#*/}
SCRIPT_CURRENT_PATH=${0%/*}
SCRIPT_ABSOLUTE_PATH=`cd $(dirname ${0}); pwd`
PROJECT_ROOT=${SCRIPT_ABSOLUTE_PATH}/.. # 工程的源码目录，一定要和编译脚本是同一个目录

source "$PROJECT_ROOT/common/common.sh"

# ========================================================
# 功能实现
# ========================================================
EXECUTE_MODE=manu
function usage()
{
    prt "================================================="
    prt "${PINK}./${SCRIPT_NAME}      : 根据菜单选择功能${CLS}"
    prt "${PINK}./${SCRIPT_NAME} -h   : 显示打印信息用法后显示菜单${CLS}"
    prt "${PINK}./${SCRIPT_NAME} -a   : 自动执行所有步骤${CLS}"
    prt "================================================="
}
# 脚本运行参数处理
notice "There are $# parameters: $@ (\$1~\$$#)"
while getopts "ahp:" arg #选项后面的冒号表示该选项需要参数
    do
        case ${arg} in
            a) EXECUTE_MODE="auto" ;;
            h)
                log_echo_demo
                ;;
            p)
                if [ $OPTARG == "1" ];then
                    message "OPTARG=$OPTARG"
                fi
                ;;
            ?)  #当有不认识的选项的时候arg为?
                error "unkonw argument..."
                exit 1
                ;;
        esac
    done

# 功能函数实现
# ========================================================
# 原始数组定义
basic_packages=(vim git gcc make g++ gzip bzip2 tar wget)
kernel_required_packages=(bison flex lzop libncurses5-dev)
buildroot_required_packages=(sed make binutils build-essential gcc g++ bash patch gzip \
                                bzip2 perl tar cpio unzip rsync file bc wget g++-multilib)

# 系统环境检查
function check_environment() 
{
    # 检查是否为Debian系系统
    if ! grep -qiE 'ubuntu|debian' /etc/os-release; then
        error "错误: 本脚本仅适用于Ubuntu/Debian系统" >&2
        exit 1
    fi
}

# 包管理核心功能
function install_packages() 
{
    # 高效数组合并去重
    declare -A pkg_map
    local all_packages=(
        "${basic_packages[@]}"
        "${kernel_required_packages[@]}"
        "${buildroot_required_packages[@]}"
    )

    for pkg in "${all_packages[@]}"; do
        pkg_map["$pkg"]=1
    done

    local unique_packages=("${!pkg_map[@]}")

    # 精确检测未安装的包
    local missing_packages=()
    for pkg in "${unique_packages[@]}"; do
        if ! dpkg-query -W --showformat='${Status}' "$pkg" 2>/dev/null | grep -q "install ok installed"; then
            missing_packages+=("$pkg")
        fi
    done

    # 安装逻辑
    if [ ${#missing_packages[@]} -gt 0 ]; then
        prt "需要安装的依赖包 (${#missing_packages[@]}个):"
        prt "  - %s" "${missing_packages[@]}"

        # 更新软件源缓存
        prt "更新软件源信息..."
        if ! execute apt-get update; then
            prt "软件源更新失败，请检查网络连接或镜像配置" >&2
            exit 1
        fi

        # 批量安装
        prt "开始安装..."
        if execute apt-get install -y --no-install-recommends "${missing_packages[@]}"; then
            success "成功安装所有依赖包"
        else
            warning "安装过程中出现错误，尝试以下解决方法：" >&2
            prt "1. 手动执行:sudo apt-get install ${missing_packages[*]}"
            prt "2. 检查软件包名称是否变化: apt-cache search <package-name>"
            prt "3. 确认系统版本兼容性"
            exit 1
        fi
    else
       success "所有依赖包已安装，无需额外操作"
    fi
}

# 自动执行所有步骤
function auto_setup() 
{
    check_environment
    install_packages
    success "所有步骤执行完成!"
}

# 菜单与主进程
# ========================================================
function show_menu()
{
    message "================================================="
    message "                script by @苏木    ${CLS}"
    message "================================================="
    prt "${PINK}current path         :$(pwd)${CLS}"
    prt "${PINK}PROJECT_ROOT         :${PROJECT_ROOT}${CLS}"
    echo ""
    prt "* [0] 安装所有的依赖包"
    echo "================================================="
}

# 主逻辑
function main() 
{
    if [ "$EXECUTE_MODE" = "manu" ]; then
        while true; do
            show_menu
            read -p "请选择操作 (0-5): " choice
            case "${choice}" in
                "0") 
                    check_environment
                    install_packages
                    ;;
                *) error "无效选项!!!" ;;
            esac
            read -p "按回车继续..."
        done
    else
        info "正在自动执行所有配置步骤..."
        auto_setup
    fi
}

# 执行入口
# show_menu # 菜单显示
main "$@" # 主逻辑执行
